package jalgebrava.group.algorithms.general;


import jalgebrava.group.Group;
import jalgebrava.group.Subgroup;
import jalgebrava.group.Subset;

import java.util.HashSet;
import java.util.Set;

public class GeneralGroupAlgorithms {

	public final static <G> Subgroup<G> extendSubgroup(Subgroup<G> s, G x) {
		Set<G> set = s.getCopyOfSet();
		set.add(x);
		Subset<G> s1 = new Subset<G>(s.getGroup(), set);
		return Subgroup.generate(s1);
	}
	public final static <G> Set<Subgroup<G>> allSubgroups(Group<G> g) {
		Set<Subgroup<G>> result = new HashSet<Subgroup<G>>();
		Set<Subgroup<G>> newSubgroups = new HashSet<Subgroup<G>>();
		newSubgroups.add(Subgroup.generate(g.unitElement()));
		boolean finished = false;
		while (!finished) {
			result.addAll(newSubgroups);
						
			newSubgroups = new HashSet<Subgroup<G>>();
			finished = true;
			
			for (Subgroup<G> s: result) {
				for (G x: g) {
					if (s.contains(x)) {
						continue;
					}
					System.out.println("Checking " + x + " and " + s);
					Subgroup<G> newSubgroup = extendSubgroup(s,x);
					if (!result.contains(newSubgroup)) {
						if (newSubgroups.contains(newSubgroup)) {
							continue;
						}
						finished = false;						
						System.out.println("Adding new subgroup " + newSubgroup);
						newSubgroups.add(newSubgroup);
					}
				}
			}
		}
		return result;
	}
}
